﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Surface;
using Microsoft.Surface.Presentation;
using Microsoft.Surface.Presentation.Controls;
using Microsoft.Surface.Presentation.Controls.Primitives;
using Microsoft.Surface.Presentation.Input;
using System.Collections.ObjectModel;
using System.Windows.Controls.DataVisualization;
using navigation.Data;
using navigation.Helpers;
using navigation.Controls;

namespace navigation.Contents
{
    /// <summary>
    /// Interaction logic for BacklogScreen.xaml
    /// </summary>
    public partial class BacklogScreen : UserControl
    {
        public BacklogScreen()
        {
            InitializeComponent();
            SetupMenuCommand();
            SetupStoryCardCommand();
            SetupBacklogCommand();
        }

        private const int DragThreshold = 2;
       

        # region private variables
        
        public static DependencyProperty ProductBacklogItemsProperty = DependencyProperty.Register("ProductBacklogItems", typeof(ObservableCollection<UserStory>), typeof(BacklogScreen));

        public ObservableCollection<UserStory> ProductBacklogItems
        {
            get
            {
                return (ObservableCollection<UserStory>)GetValue(BacklogScreen.ProductBacklogItemsProperty);
            }
            set
            {
                SetValue(BacklogScreen.ProductBacklogItemsProperty, value);
            }
        }

        public static DependencyProperty SprintBacklogItemsProperty = DependencyProperty.Register("SprintBacklogItems", typeof(ObservableCollection<UserStory>), typeof(BacklogScreen));

        public ObservableCollection<UserStory> SprintBacklogItems
        {
            get
            {
                return (ObservableCollection<UserStory>)GetValue(BacklogScreen.SprintBacklogItemsProperty);
            }
            set
            {
                SetValue(BacklogScreen.SprintBacklogItemsProperty, value);
            }
        }       

        #endregion

        # region Product Backlog Operation

        private void ListBoxOnDragSourcePreviewTouchDown(object sender, InputEventArgs e)
        {
            Vector draggedDelta = InputDeviceHelper.DraggedDelta(e.Device, (UIElement)ProductBacklog);
           
            // If this input device has moved more than Threshold pixels vertically 
            // then this is not a drag-and-drop yet.
            if (Math.Abs(draggedDelta.Y) > DragThreshold)
            {
                //ignoredDeviceList.Add(e.Device);
                return;
            }
            
            FrameworkElement findSource = e.OriginalSource as FrameworkElement;
            SurfaceListBoxItem draggedElement = null;
            FrameworkElement sourceHelper = findSource;  

            // Find the touched SurfaceListBoxItem object.
            while (draggedElement == null && findSource != null)
            {
                if ((draggedElement = findSource as SurfaceListBoxItem) == null)
                {
                    findSource = VisualTreeHelper.GetParent(findSource) as FrameworkElement;
                }
            }

            if (draggedElement == null || sourceHelper is Border)
            {
                return;
            }
            
            SurfaceToggleButton stb = null;
            stb = FindContainer<SurfaceToggleButton>(stb, sourceHelper);
            if (stb != null)
            {
                return;
            }

            //UserStory data = draggedElement.Content as UserStory;

            //data.DraggedElement = draggedElement;

            // Create the cursor visual.
            ContentControl cursorVisual = new ContentControl()
            {
                Content = draggedElement.DataContext,
                Style = FindResource("CursorStyle") as Style
            };

            // Create a list of input devices. Add the touches that
            // are currently captured within the dragged element and
            // the current touch (if it isn't already in the list).
            List<InputDevice> devices = new List<InputDevice>();
            devices.Add(e.Device);
            foreach (InputDevice device in draggedElement.TouchesCapturedWithin)
            {
                if (device != e.Device)
                {
                    devices.Add(device);
                }
            }

            // Get the drag source object
            ItemsControl dragSource = ItemsControl.ItemsControlFromItemContainer(draggedElement);

            SurfaceDragCursor startDragOkay =
                SurfaceDragDrop.BeginDragDrop(
                  dragSource,                 // The SurfaceListBox object that the cursor is dragged out from.
                  draggedElement,             // The SurfaceListBoxItem object that is dragged from the drag source.
                  cursorVisual,               // The visual element of the cursor.
                  draggedElement.DataContext, // The data associated with the cursor.
                  devices,                    // The input devices that start dragging the cursor.
                  DragDropEffects.Move);      // The allowed drag-and-drop effects of the operation.

            // If the drag began successfully, set e.Handled to true. 
            // Otherwise SurfaceListBoxItem captures the touch 
            // and causes the drag operation to fail.
            e.Handled = (startDragOkay != null);
            draggedElement.Visibility = System.Windows.Visibility.Hidden;
        }

        private void ProductBacklog_OnDropTargetDrop(object sender, SurfaceDragDropEventArgs e)
        {
            if (e.Cursor.Data is UserStory)
            {
                if (ProductBacklogItems.Contains(e.Cursor.Data as UserStory))
                {
                    int index = this.GetListBoxItemCurrentIndex(ProductBacklog, e.Cursor.GetPosition);
                    int indexOfDraggedElement = ProductBacklogItems.IndexOf(e.Cursor.Data as UserStory);

                    if (index < 0 || index > ProductBacklog.Items.Count - 1)
                    {
                        UserStory temp = ProductBacklogItems[indexOfDraggedElement];
                        ProductBacklogItems.RemoveAt(indexOfDraggedElement);
                        ProductBacklogItems.Add(temp);
                    }
                    else
                    {
                        UserStory temp = ProductBacklogItems[indexOfDraggedElement];
                        ProductBacklogItems.RemoveAt(indexOfDraggedElement);
                        ProductBacklogItems.Insert(index, e.Cursor.Data as UserStory);
                    }
                }
                else
                {
                    int index = this.GetListBoxItemCurrentIndex(ProductBacklog, e.Cursor.GetPosition);

                    if (index < 0 || index > ProductBacklog.Items.Count - 1)
                        index = ProductBacklog.Items.Count;
                    if (ScatterView.Items.Contains(e.Cursor.Data as UserStory))
                    {
                        ScatterView.Items.Remove(e.Cursor.Data as UserStory);
                    }
                    ProductBacklogItems.Insert(index, e.Cursor.Data as UserStory);
                }
            }
        }

        private void ProductBacklog_DragCanceled(object sender, SurfaceDragDropEventArgs e)
        {
            foreach (UserStory item in ProductBacklog.Items)
            {
                SurfaceListBoxItem temp = ProductBacklog.ItemContainerGenerator.ContainerFromItem(item) as SurfaceListBoxItem;
                if (temp.Visibility == System.Windows.Visibility.Hidden)
                    temp.Visibility = System.Windows.Visibility.Visible;
            }
        }

        private void ProductBacklog_DragCompleted(object sender, SurfaceDragCompletedEventArgs e)
        {
            UserStory data = e.Cursor.Data as UserStory;
            SurfaceListBoxItem temp = ProductBacklog.ItemContainerGenerator.ContainerFromItem(data) as SurfaceListBoxItem;
            if (temp != null)
            {
                if (ScatterView.Items.Contains(data) || SprintBacklogItems.Contains(data))
                {
                    temp.Visibility = System.Windows.Visibility.Visible;
                    temp.IsEnabled = false;
                    temp.Opacity = 0.5;
                }
                else
                {
                    temp.Visibility = System.Windows.Visibility.Visible;
                }
            }
        }

        # endregion

        # region ScatterView Operation  
      
        private void ScatterViewOnDragSourcePreviewTouchDown(object sender, TouchEventArgs e)
        {           
            if (e.Device.GetIsFingerRecognized())
            {               
                FrameworkElement findSource = e.OriginalSource as FrameworkElement;
                ScatterViewItem draggedElement = null;
                FrameworkElement sourceHelper = findSource;
               
                // Find the ScatterViewItem object that is being touched.
                while (draggedElement == null && findSource != null)
                {
                    if ((draggedElement = findSource as ScatterViewItem) == null)
                    {
                        findSource = VisualTreeHelper.GetParent(findSource) as FrameworkElement;                        
                    }
                }

                //if (draggedElement == null)
                //{
                //    FlipStoryCard fsc = null;
                //    FrameworkElement findSource2 = e.OriginalSource as FrameworkElement;
                //    while (fsc == null && findSource2 != null)
                //    {
                //        if ((fsc = findSource2 as FlipStoryCard) == null)
                //        {
                //            findSource2 = LogicalTreeHelper.GetParent(findSource2) as FrameworkElement;
                //        }
                //    }

                //    while (draggedElement == null && findSource2 != null)
                //    {
                //        if ((draggedElement = findSource2 as ScatterViewItem) == null)
                //        {
                //            findSource2 = VisualTreeHelper.GetParent(findSource2) as FrameworkElement;
                //        }
                //    }
                //}

                if (draggedElement == null)
                {                    
                    return;
                }

                // if the touch target is textbox
                if (sourceHelper.GetType().Name == "TextBoxView")
                {
                    SurfaceTextBox stb = FocusTextBox(sourceHelper);
                    e.Handled = true;
                    stb.Focus();                    
                    //Console.WriteLine(draggedElement);
                    //SetKeyboardFocus(draggedElement, stb);
                    //if the textbox is editable
                    if (stb.Focusable == true)
                        return;
                }

                BurnDownChart bdc = null;
                bdc = FindContainer<BurnDownChart>(bdc, sourceHelper);

                SurfaceListBox slb = null;
                slb = FindContainer<SurfaceListBox>(slb, sourceHelper);
                if (slb != null || bdc != null)
                {
                    return;
                }

                ContentControl cursorVisual;

                if (draggedElement.Content is UserStory)
                {
                    UserStory data = draggedElement.Content as UserStory;

                    // If the data has not been specified as draggable, 
                    // or the ScatterViewItem cannot move, return.
                    if (data == null || !draggedElement.CanMove)
                    {
                        return;
                    }

                    // Set the dragged element. This is needed in case the drag operation is canceled.
                    data.DraggedElement = draggedElement;

                    // Create the cursor visual.
                    cursorVisual = new ContentControl()
                    {
                        Content = draggedElement.DataContext,
                        Style = FindResource("ScatterCursorStyle") as Style
                    };
                }
                else
                {
                    Task data = draggedElement.Content as Task;

                    // If the data has not been specified as draggable, 
                    // or the ScatterViewItem cannot move, return.
                    if (data == null || !draggedElement.CanMove)
                    {
                        return;
                    }

                    // Set the dragged element. This is needed in case the drag operation is canceled.
                    data.DraggedElement = draggedElement;

                    cursorVisual = new ContentControl()
                    {
                        Content = draggedElement.DataContext,
                        Style = FindResource("ScatterTaskCursorStyle") as Style
                    };
                }


                // Create a list of input devices, 
                // and add the device passed to this event handler.
                List<InputDevice> devices = new List<InputDevice>();
                devices.Add(e.Device);

                // If there are touch devices captured within the element,
                // add them to the list of input devices.
                foreach (InputDevice device in draggedElement.TouchesCapturedWithin)
                {
                    if (device != e.Device)
                    {
                        devices.Add(device);
                    }
                }

                // Get the drag source object.
                ItemsControl dragSource = ItemsControl.ItemsControlFromItemContainer(draggedElement);

                // Start the drag-and-drop operation.
                SurfaceDragCursor cursor =
                    SurfaceDragDrop.BeginDragDrop(
                    // The ScatterView object that the cursor is dragged out from.
                      dragSource,
                    // The ScatterViewItem object that is dragged from the drag source.
                      draggedElement,
                    // The visual element of the cursor.
                      cursorVisual,
                    // The data attached with the cursor.
                      draggedElement.DataContext,
                    // The input devices that start dragging the cursor.
                      devices,
                    // The allowed drag-and-drop effects of the operation.
                      DragDropEffects.Move);

                // If the cursor was created, the drag-and-drop operation was successfully started.
                if (cursor != null)
                {
                    // Hide the ScatterViewItem.
                    draggedElement.Visibility = Visibility.Hidden;

                    // This event has been handled.
                    e.Handled = true;
                }
            }

        }

        private void ScatterViewTargetDrop(object sender, SurfaceDragDropEventArgs e)
        {
            //Console.WriteLine(sender);
            //Console.WriteLine(e.OriginalSource);
            //Console.WriteLine(e.Cursor.Data);
            if (e.Cursor.Data is UserStory)
            {
                UserStory data = e.Cursor.Data as UserStory;
                if (!ScatterView.Items.Contains(data))
                {
                    ScatterView.Items.Add(data);
                    ScatterViewItem item = ScatterView.ItemContainerGenerator.ContainerFromItem(data) as ScatterViewItem;
                    if (data.ShowTaskList == "Visible")
                    {
                        data.ShowTaskList = "Collapsed";
                    }
                    item.Width = 300;
                    item.Height = 170;
                    item.Background = new SolidColorBrush(Colors.Transparent);
                    item.Orientation = e.Cursor.GetOrientation(this);
                    item.Center = e.Cursor.GetPosition(this.ScatterView);
                }
                else
                {
                    ScatterViewItem item = ScatterView.ItemContainerGenerator.ContainerFromItem(data) as ScatterViewItem;
                    if (item != null)
                    {
                        item.Visibility = Visibility.Visible;
                        item.Background = new SolidColorBrush(Colors.Transparent);
                        item.Orientation = e.Cursor.GetOrientation(this);
                        item.Center = e.Cursor.GetPosition(this.ScatterView);
                    }
                }
            }
            else
            {
                if (e.Cursor.CurrentTarget.DataContext is UserStory)
                {
                    //Console.WriteLine((e.Cursor.CurrentTarget.DataContext as UserStory).StoryName);
                    UserStory story = e.Cursor.CurrentTarget.DataContext as UserStory;
                    ScatterViewItem itemtemp = ScatterView.ItemContainerGenerator.ContainerFromItem(story) as ScatterViewItem;
                    double orit = itemtemp.Orientation;
                    Point posi = itemtemp.Center;
                    //////////////////////////////////////////
                    //Console.WriteLine("origin:"+itemtemp.Height);
                    //Console.WriteLine("originMax:"+itemtemp.MaxHeight);
                    //Grid gridtemp = VisualTreeHelper.GetChild(itemtemp,0) as Grid;
                    //Console.WriteLine("originContent:"+gridtemp.Height);
                    //////////////////////////////////////////
                    Task temptask = e.Cursor.Data as Task;
                    story.TaskList.Add(e.Cursor.Data as Task);
                    ScatterView.Items.Remove(e.Cursor.Data as Task);
                    if (temptask.State == null)
                    {
                        temptask.State = "Planned";
                    }
                    story.Planned.Add(temptask);
                    temptask.StoryName = story.StoryName;
                    ScatterViewItem item = ScatterView.ItemContainerGenerator.ContainerFromItem(story) as ScatterViewItem;
                    item.Background = new SolidColorBrush(Colors.Transparent);
                    item.Orientation = orit;
                    item.Center = posi;
                }
                else
                {
                    if (ScatterView.Items.Contains(e.Cursor.Data))
                    {
                        Task data = e.Cursor.Data as Task;
                        ScatterViewItem item = ScatterView.ItemContainerGenerator.ContainerFromItem(data) as ScatterViewItem;
                        if (item != null)
                        {
                            item.Visibility = Visibility.Visible;
                            item.Background = new SolidColorBrush(Colors.Transparent);
                            item.Orientation = e.Cursor.GetOrientation(this);
                            item.Center = e.Cursor.GetPosition(this.ScatterView);
                            
                        }
                    }
                    else
                    {
                        Task data = e.Cursor.Data as Task;
                        ScatterView.Items.Add(data);
                        ScatterViewItem item = ScatterView.ItemContainerGenerator.ContainerFromItem(data) as ScatterViewItem;
                        if (item != null)
                        {
                            item.Visibility = Visibility.Visible;
                            item.Background = new SolidColorBrush(Colors.Transparent);
                            item.Orientation = e.Cursor.GetOrientation(this);
                            item.Center = e.Cursor.GetPosition(this.ScatterView);
                        }
                    }
                }
            }
        }        

        private void ScatterViewDragCompleted(object sender, SurfaceDragCompletedEventArgs e)
        {
            // If the operation is Move, remove the data from drag source.
            if (e.Cursor.Data is UserStory)
            {
                if (e.Cursor.Effects == DragDropEffects.Move)
                {
                    if (e.Cursor.CurrentTarget == ProductBacklog || e.Cursor.CurrentTarget == SprintBacklog)
                        ScatterView.Items.Remove(e.Cursor.Data as UserStory);
                }
            }
            else
            {
                ScatterViewItem item = ScatterView.ItemContainerGenerator.ContainerFromItem(e.Cursor.Data) as ScatterViewItem;
                if (item != null)
                    item.Visibility = System.Windows.Visibility.Visible;
            }
        }

        # endregion

        # region Sprint Backlog Operation

        private void SprintBacklog_OnDropTargetDrop(object sender, SurfaceDragDropEventArgs e)
        {
            if (e.Cursor.Data is UserStory)
            {
                if (SprintBacklogItems.Contains(e.Cursor.Data as UserStory))
                {
                    int index = this.GetListBoxItemCurrentIndex(SprintBacklog, e.Cursor.GetPosition);
                    int indexOfDraggedElement = SprintBacklogItems.IndexOf(e.Cursor.Data as UserStory);

                    if (index < 0 || index > SprintBacklog.Items.Count - 1)
                    {
                        UserStory temp = SprintBacklogItems[indexOfDraggedElement];
                        SprintBacklogItems.RemoveAt(indexOfDraggedElement);
                        SprintBacklogItems.Add(temp);
                    }
                    else
                    {
                        UserStory temp = SprintBacklogItems[indexOfDraggedElement];
                        SprintBacklogItems.RemoveAt(indexOfDraggedElement);
                        SprintBacklogItems.Insert(index, e.Cursor.Data as UserStory);
                    }
                }
                else
                {
                    int index = this.GetListBoxItemCurrentIndex(SprintBacklog, e.Cursor.GetPosition);
                    //UserStory temp = e.Cursor.Data as UserStory;

                    if (index < 0 || index > SprintBacklog.Items.Count - 1)
                        index = SprintBacklog.Items.Count;

                    if (ScatterView.Items.Contains(e.Cursor.Data as UserStory))
                    {
                        ScatterView.Items.Remove(e.Cursor.Data as UserStory);
                    }
                    if (((UserStory)e.Cursor.Data).State == "Red")
                    {
                        ((UserStory)e.Cursor.Data).State = "Yellow";
                    }
                    SprintBacklogItems.Insert(index, e.Cursor.Data as UserStory);
                }
            }
        }

        private void SprintBacklog_DragCanceled(object sender, SurfaceDragDropEventArgs e)
        {
            foreach (UserStory item in SprintBacklog.Items)
            {
                SurfaceListBoxItem temp = SprintBacklog.ItemContainerGenerator.ContainerFromItem(item) as SurfaceListBoxItem;
                if (temp.Visibility == System.Windows.Visibility.Hidden)
                    temp.Visibility = System.Windows.Visibility.Visible;
            }
        }

        private void SprintBacklog_DragCompleted(object sender, SurfaceDragCompletedEventArgs e)
        {
            if (e.Cursor.CurrentTarget != SprintBacklog)
                SprintBacklogItems.Remove(e.Cursor.Data as UserStory);
        }

        # endregion

        #region help function for listbox insertion

        // controls to help swap and insert task cards inside the listbox
        public delegate Point GetDragDropPosition(IInputElement theElement);

        private bool isTheCursorOnTarget(Visual target, GetDragDropPosition pos)
        {
            Rect posBounds = VisualTreeHelper.GetDescendantBounds(target);
            Point theCursorPos = pos((IInputElement)target);
            return posBounds.Contains(theCursorPos);
        }

        private ListBoxItem GetListBoxItem(ListBox listBox, int index)
        {
            if (listBox.ItemContainerGenerator.Status != System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated)
                return null;
            return listBox.ItemContainerGenerator.ContainerFromIndex(index) as ListBoxItem;
        }

        private int GetListBoxItemCurrentIndex(ListBox listBox, GetDragDropPosition pos)
        {
            int curIndex = -1;
            for (int i = 0; i < listBox.Items.Count; i++)
            {
                ListBoxItem item = GetListBoxItem(listBox, i);
                if (isTheCursorOnTarget(item, pos))
                {
                    curIndex = i;
                    break;
                }
            }
            return curIndex;
        }

        #endregion

        #region RoutedCommand

        public static readonly RoutedCommand ScatterViewDeleteTaskCardCommand = new RoutedCommand("ScatterViewDeleteTaskCard", typeof(BacklogScreen));

        public static readonly RoutedCommand ShowTaskListCommand = new RoutedCommand("ShowTaskList", typeof(BacklogScreen));

        public static readonly RoutedCommand BacklogItemShowContentCommand = new RoutedCommand("BacklogItemShowContent", typeof(BacklogScreen));

        public static readonly RoutedCommand ScatterViewTaskCardEditSwitchCommand = new RoutedCommand("ScatterViewTaskCardEditSwitch", typeof(BacklogScreen));

        public static readonly RoutedCommand StoryCardMenuEditCommand = new RoutedCommand("StoryCardMenuEdit", typeof(BacklogScreen));

        public static readonly RoutedCommand ShowMessageCommand = new RoutedCommand("ShowMessage", typeof(BacklogScreen));
        
        private void SetupMenuCommand()
        {
            CommandManager.RegisterClassCommandBinding(typeof(BacklogScreen),
                new CommandBinding(BacklogScreen.ScatterViewDeleteTaskCardCommand, new ExecutedRoutedEventHandler(ProcessDeleteTaskCardCommand)));

            CommandManager.RegisterClassCommandBinding(typeof(BacklogScreen),
                new CommandBinding(BacklogScreen.ScatterViewTaskCardEditSwitchCommand, new ExecutedRoutedEventHandler(ProcessScatterViewTaskCardEditSwitch)));
            
            CommandManager.RegisterClassCommandBinding(typeof(BacklogScreen),
                new CommandBinding(BacklogScreen.StoryCardMenuEditCommand, new ExecutedRoutedEventHandler(StoryCardMenuEdit)));

            CommandManager.RegisterClassCommandBinding(typeof(BacklogScreen),
                new CommandBinding(BacklogScreen.ShowMessageCommand, new ExecutedRoutedEventHandler(ShowMessage)));
        }

        private void SetupStoryCardCommand()
        {
            CommandManager.RegisterClassCommandBinding(typeof(BacklogScreen),
                new CommandBinding(BacklogScreen.ShowTaskListCommand, new ExecutedRoutedEventHandler(ProcessShowTaskList)));           
        }

        private void SetupBacklogCommand()
        {
            CommandManager.RegisterClassCommandBinding(typeof(BacklogScreen),
                new CommandBinding(BacklogScreen.BacklogItemShowContentCommand, new ExecutedRoutedEventHandler(ProcessBacklogItemShowContent)));
        }

        private void ProcessShowTaskList(object sender, ExecutedRoutedEventArgs args)
        {   
            ScatterViewItem svi = null;
            FrameworkElement findsource = args.Parameter as FrameworkElement;

            while (svi == null && findsource != null)
            {
                if ((svi = findsource as ScatterViewItem) == null)
                {
                    findsource = VisualTreeHelper.GetParent(findsource) as FrameworkElement;
                }
            }

            SurfaceButton sfb = FindVisualChildByName<SurfaceButton>(svi, "taskListButton");  
            UserStory us = svi.DataContext as UserStory;
            Canvas cav = args.Parameter as Canvas;            

            if (us.ShowTaskList == "Collapsed")
            {
                us.ShowTaskList = "Visible";
                svi.Height += cav.Height;
                sfb.Content = "close task list";
            }
            else
            {
                us.ShowTaskList = "Collapsed";
                svi.Height -= cav.Height;
                sfb.Content = "open task list";
            }
        }

        private void ProcessDeleteTaskCardCommand(object sender, ExecutedRoutedEventArgs args)
        {
            if (ScatterView.Items.Contains((Task)args.Parameter))
            {
                ScatterView.Items.Remove((Task)args.Parameter);
            }
        }

        private void ProcessBacklogItemShowContent(object sender, ExecutedRoutedEventArgs args)
        {
            Console.WriteLine("1");
            UserStory us = args.Parameter as UserStory;
            if (us.StoryContentState == "Collapsed")
            {
                us.StoryContentState = "Visibile";
            }
            else
            {
                us.StoryContentState = "Collapsed";
            }
        }

        private void ProcessScatterViewTaskCardEditSwitch(object sender, ExecutedRoutedEventArgs args)
        {
            Task task = args.Parameter as Task;
            ScatterViewItem svi = ScatterView.ItemContainerGenerator.ContainerFromItem(task) as ScatterViewItem;
            SurfaceTextBox TaskNameTextBox = FindVisualChildByName<SurfaceTextBox>(svi, "TaskNameTextBox");
            SurfaceTextBox TaskContentBox = FindVisualChildByName<SurfaceTextBox>(svi, "TaskContentTextBox");
            if (task.IsTaskCardEditable == "True")
            {
                task.IsTaskCardEditable = "False";
                TaskNameTextBox.Focusable = false;
                TaskContentBox.Focusable = false;
            }
            else
            {
                task.IsTaskCardEditable = "True";
                TaskNameTextBox.Focusable = true;
                TaskContentBox.Focusable = true;
            }
        }

        private void StoryCardMenuEdit(object sender, ExecutedRoutedEventArgs args)
        {
            UserStory us = args.Parameter as UserStory;
            ScatterViewItem svi = ScatterView.ItemContainerGenerator.ContainerFromItem(us) as ScatterViewItem;
            SurfaceTextBox StoryNameTextBox = FindVisualChildByName<SurfaceTextBox>(svi, "StoryNameTextBox");
            SurfaceTextBox StoryContentTextBox = FindVisualChildByName<SurfaceTextBox>(svi, "StoryContentTextBox");

            if (StoryNameTextBox.Focusable == true)
            {
                StoryNameTextBox.Focusable = false;
                StoryContentTextBox.Focusable = false;

                StoryNameTextBox.IsEnabled = false;
                StoryContentTextBox.IsEnabled = false;
            }
            else
            {
                StoryNameTextBox.Focusable = true;
                StoryContentTextBox.Focusable = true;

                StoryNameTextBox.IsEnabled = true;
                StoryContentTextBox.IsEnabled = true;
            }
        }

        private void ShowMessage(object sender, ExecutedRoutedEventArgs args)
        {
            MessageBox.Show(args.Parameter + " Clicked");
        }

        #endregion

        # region Help function

        public static T FindVisualChildByName<T>(DependencyObject parent, string name) where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
            {
                var child = VisualTreeHelper.GetChild(parent, i);
                string controlName = child.GetValue(Control.NameProperty) as string;

                if (controlName == name)
                {
                    return child as T;
                }
                else
                {
                    T result = FindVisualChildByName<T>(child, name);
                    if (result != null)
                        return result;
                }
            }
            return null;
        }

        public T FindContainer<T>(T containerElement, FrameworkElement findsource) where T : DependencyObject
        {
            while (containerElement == null && findsource != null)
            {
                if ((containerElement = findsource as T) == null)
                {
                    findsource = VisualTreeHelper.GetParent(findsource) as FrameworkElement;
                }
            }

            return containerElement;
        }

        public SurfaceTextBox FocusTextBox(FrameworkElement findSource)
        {              
            SurfaceTextBox stb = null;
            while (stb == null && findSource != null)
            {
                if ((stb = findSource as SurfaceTextBox) == null)
                {
                    findSource = VisualTreeHelper.GetParent(findSource) as FrameworkElement;
                }
            }
            //Console.WriteLine(stb);
           
            //stb.Focus();             
            //Keyboard.Focus(stb);
            return stb;
        }

        public void SetKeyboardFocus(ScatterViewItem svi, SurfaceTextBox stb)
        {
            Keyboard.Focus(stb);
            float distance = (float) (svi.ActualHeight/2 + 170);
            float theta = (float) svi.Orientation;            
            SurfaceKeyboard.Rotation = (float)(Math.PI * theta / 180.0);
            //bug
            //if (theta >= 0 && theta < 90)
            //{
            //    SurfaceKeyboard.CenterX = (float)(svi.Center.X - distance * Math.Sin(theta));
            //    SurfaceKeyboard.CenterY = (float)(svi.Center.Y + distance * Math.Cos(theta));
            //}
            //else if (theta >= 90 && theta < 180)
            //{
            //    SurfaceKeyboard.CenterX = (float)(svi.Center.X - distance * Math.Sin(theta));
            //    SurfaceKeyboard.CenterY = (float)(svi.Center.Y - distance * Math.Cos(theta));
            //}
            //else if (theta >= 180 && theta < 270)
            //{
            //    SurfaceKeyboard.CenterX = (float)(svi.Center.X + distance * Math.Sin(theta));
            //    SurfaceKeyboard.CenterY = (float)(svi.Center.Y - distance * Math.Cos(theta));
            //}
            //else
            //{
            //    SurfaceKeyboard.CenterX = (float)(svi.Center.X + distance * Math.Sin(theta));
            //    SurfaceKeyboard.CenterY = (float)(svi.Center.Y + distance * Math.Cos(theta));
            //}            
           
        }

        #endregion

        #region Datatemplate events

        private void SurfaceToggleButton_Click(object sender, RoutedEventArgs e)
        {
            SurfaceToggleButton stb = e.OriginalSource as SurfaceToggleButton;
            SurfaceListBoxItem draggedElement = null;

            draggedElement = FindContainer<SurfaceListBoxItem>(draggedElement, stb);
            if (draggedElement != null)
            {
                UserStory story = draggedElement.DataContext as UserStory;

                if (story.StoryContentState == "Collapsed")
                {
                    story.StoryContentState = "Visible";
                }
                else
                {
                    story.StoryContentState = "Collapsed";
                }
            }
        }

        #endregion

        private void SurfaceButton_Click(object sender, RoutedEventArgs e)
        {
            if (canvas.Tag.ToString() == "Closed")
            {
                (Resources["canvas.Open"] as Storyboard).Begin(this);
                canvas.Tag = "Opened";
            }
            else
            {
                (Resources["canvas.Close"] as Storyboard).Begin(this);
                canvas.Tag = "Closed";
            }
        }

        private void Visualizer_VisualizationAdded(object sender, TagVisualizerEventArgs e)
        {
            //Console.WriteLine(e.TagVisualization.Center);
            //Console.WriteLine(e.TagVisualization.VisualizedTag.Value);
            if (e.TagVisualization.VisualizedTag.Value == 10)
            {
                ObservableCollection<Task> tasks = new ObservableCollection<Task>();
                UserStory newstory = new UserStory("story name", "planned", "story contents", 20, tasks);
                ScatterView.Items.Add(newstory);
                ScatterViewItem item = ScatterView.ItemContainerGenerator.ContainerFromItem(newstory) as ScatterViewItem;
                if (newstory.ShowTaskList == "Visible")
                {
                    newstory.ShowTaskList = "Collapsed";
                }
                item.Width = 300;
                item.Height = 170;
                item.Background = new SolidColorBrush(Colors.Transparent);
                item.Orientation = e.TagVisualization.Orientation;
                item.Center = e.TagVisualization.Center;
            }
        }

        #region try scale vertically

        //private bool productBacklogUpTouch = false;
        //private bool sprintBacklogUpTouch = false;
        //private Point productbacklogcurrentposition;
        //private Point productbacklogtitileposition;
        //private Point sprintbacklogcurrentposition;
        //private Point sprintbacklogtitleposition;
        //private Point tempPosition;

        //private void ProductBacklogUpTextBlock_PreviewTouchDown(object sender, TouchEventArgs e)
        //{
        //    productBacklogUpTouch = true;
        //    Console.WriteLine("up"+productBacklogUpTouch);
        //    productbacklogcurrentposition = e.Device.GetPosition(ScatterView);
        //    productbacklogtitileposition = productbacklogcurrentposition;
        //    productbacklogcurrentposition.Y += ProductBacklog.Height;                 
        //}

        //private void ProductBacklogUpTextBlock_TouchUp(object sender, TouchEventArgs e)
        //{
        //    productBacklogUpTouch = false;
        //    Console.WriteLine("up" + productBacklogUpTouch);
        //}        

        //private void ScatterView_TouchMove(object sender, TouchEventArgs e)
        //{
        //    tempPosition = e.Device.GetPosition(ScatterView);
        //    if (productBacklogUpTouch == true)
        //        //&& tempPosition.Y > (productbacklogtitileposition.Y + ProductSVI.Height) 
        //        //&& tempPosition.Y < (productbacklogtitileposition.Y + ProductSVI.Height + 20) 
        //        //&& tempPosition.X < (productbacklogtitileposition.X + 150) 
        //        //&& tempPosition.X > (productbacklogtitileposition.X - 150) )
        //    {
        //        //tempPosition = e.Device.GetPosition(ScatterView);
        //        double increment = e.Device.GetPosition(ScatterView).Y - productbacklogcurrentposition.Y;
        //        //Console.WriteLine(increment);
        //        if ((ProductBacklog.Height + increment) > 0 && (ProductSVI.Height + increment) > 0)
        //        {
        //            ProductBacklog.Height += increment;
        //            ProductSVI.Height += increment;
        //            Point center = ProductSVI.Center;
        //            center.Y += increment / 2;
        //            ProductSVI.Center = center;
        //        } 
                
        //        //Console.WriteLine(e.GetTouchPoint(ScatterView).Position);
        //        productbacklogcurrentposition = tempPosition;               
        //    }

        //    if (sprintBacklogUpTouch == true)
        //    //&& tempPosition.Y > (productbacklogtitileposition.Y + ProductSVI.Height) 
        //    //&& tempPosition.Y < (productbacklogtitileposition.Y + ProductSVI.Height + 20) 
        //    //&& tempPosition.X < (productbacklogtitileposition.X + 150) 
        //    //&& tempPosition.X > (productbacklogtitileposition.X - 150) )
        //    {
        //        //tempPosition = e.Device.GetPosition(ScatterView);
        //        double increment = e.Device.GetPosition(ScatterView).Y - sprintbacklogcurrentposition.Y;
        //        //Console.WriteLine(increment);
        //        if ((SprintBacklog.Height + increment) > 0 && (SprintSVI.Height + increment) > 0)
        //        {
        //            SprintBacklog.Height += increment;
        //            SprintSVI.Height += increment;
        //            Point center = SprintSVI.Center;
        //            center.Y += increment / 2;
        //            SprintSVI.Center = center;
        //        }

        //        //Console.WriteLine(e.GetTouchPoint(ScatterView).Position);
        //        sprintbacklogcurrentposition = tempPosition;
        //    }
        //}

        //private void SprintBacklogUpTextBlock_PreviewTouchDown(object sender, TouchEventArgs e)
        //{
        //    sprintBacklogUpTouch = true;
        //    sprintbacklogcurrentposition = e.Device.GetPosition(ScatterView);
        //    sprintbacklogcurrentposition.Y += SprintBacklog.Height;     
        //}

        //private void SprintBacklogUpTextBlock_TouchUp(object sender, TouchEventArgs e)
        //{
        //    sprintBacklogUpTouch = false;
        //}

        # endregion

    }
}
